/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * File Name          : freertos.c
  * Description        : Code for freertos applications
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2023 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "gpio.h"
#include <stdio.h>
#include <string.h>
#include "atcmd.h"
#include "core_json.h"

#include "max30102.h"
#include "algorithm.h"
#include "xiic.h"
#include "blood.h"
#include "stm32l4xx_hal_gpio.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

#define BUFFER_SIZE 256
static uint32_t TmrCb_Count = 0; /* 记录软件定时器 1 回调函数执行次数 */

int report_tempRH_json(float *temperature,float *humidity);
int report_heart_json(int  HR,float SPO2);



extern uint8_t recvBuff[BUFFER_SIZE];  //接收数据缓存数组
volatile uint8_t recvLength = 0;  //接收�??????????帧数据的长度
volatile uint8_t recvDndFlag = 0; //�??????????帧数据接收完成标�??????????
//static uint32_t TmrCb_Count = 0; /* 记录软件定时器回调函数执行次�????????? */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */

/* USER CODE END Variables */
osThreadId defaultTaskHandle;
osThreadId Get_TaskHandle;
osThreadId Ble_TaskHandle;
osThreadId Receive_TaskHandle;
osMessageQId TestQueueHandle;
osTimerId SwtmrHandle;
osSemaphoreId BinarySemHandle;

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */

/* USER CODE END FunctionPrototypes */

void StartDefaultTask(void const * argument);
void Get_Task_Fun(void const * argument);
void Ble_Task_Fun(void const * argument);
void Receive_Task_Fun(void const * argument);
void Swtmr_Callback(void const * argument);

void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */

/* GetIdleTaskMemory prototype (linked to static allocation support) */
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize );

/* GetTimerTaskMemory prototype (linked to static allocation support) */
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize );

/* USER CODE BEGIN GET_IDLE_TASK_MEMORY */
static StaticTask_t xIdleTaskTCBBuffer;
static StackType_t xIdleStack[configMINIMAL_STACK_SIZE];


void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize )
{
  *ppxIdleTaskTCBBuffer = &xIdleTaskTCBBuffer;
  *ppxIdleTaskStackBuffer = &xIdleStack[0];
  *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
  /* place for user code */
}
/* USER CODE END GET_IDLE_TASK_MEMORY */

/* USER CODE BEGIN GET_TIMER_TASK_MEMORY */
static StaticTask_t xTimerTaskTCBBuffer;
static StackType_t xTimerStack[configTIMER_TASK_STACK_DEPTH];

void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize )
{
  *ppxTimerTaskTCBBuffer = &xTimerTaskTCBBuffer;
  *ppxTimerTaskStackBuffer = &xTimerStack[0];
  *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
  /* place for user code */
}
/* USER CODE END GET_TIMER_TASK_MEMORY */

/**
  * @brief  FreeRTOS initialization
  * @param  None
  * @retval None
  */
void MX_FREERTOS_Init(void) {
  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* USER CODE BEGIN RTOS_MUTEX */
  /* add mutexes, ... */
  /* USER CODE END RTOS_MUTEX */

  /* Create the semaphores(s) */
  /* definition and creation of BinarySem */
  osSemaphoreDef(BinarySem);
  BinarySemHandle = osSemaphoreCreate(osSemaphore(BinarySem), 1);

  /* USER CODE BEGIN RTOS_SEMAPHORES */
  /* add semaphores, ... */
  /* USER CODE END RTOS_SEMAPHORES */

  /* Create the timer(s) */
  /* definition and creation of Swtmr */
  osTimerDef(Swtmr, Swtmr_Callback);
  SwtmrHandle = osTimerCreate(osTimer(Swtmr), osTimerPeriodic, NULL);

  /* USER CODE BEGIN RTOS_TIMERS */
  /* start timers, add new ones, ... */
  /* USER CODE END RTOS_TIMERS */

  /* Create the queue(s) */
  /* definition and creation of TestQueue */
  osMessageQDef(TestQueue, 16, uint32_t);
  TestQueueHandle = osMessageCreate(osMessageQ(TestQueue), NULL);

  /* USER CODE BEGIN RTOS_QUEUES */
  /* add queues, ... */
  /* USER CODE END RTOS_QUEUES */

  /* Create the thread(s) */
  /* definition and creation of defaultTask */
  osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128);
  defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);

  /* definition and creation of Get_Task */
  osThreadDef(Get_Task, Get_Task_Fun, osPriorityLow, 0, 1024);
  Get_TaskHandle = osThreadCreate(osThread(Get_Task), NULL);

  /* definition and creation of Ble_Task */
  osThreadDef(Ble_Task, Ble_Task_Fun, osPriorityLow, 0, 512);
  Ble_TaskHandle = osThreadCreate(osThread(Ble_Task), NULL);

  /* definition and creation of Receive_Task */
  osThreadDef(Receive_Task, Receive_Task_Fun, osPriorityLow, 0, 128);
  Receive_TaskHandle = osThreadCreate(osThread(Receive_Task), NULL);

  /* USER CODE BEGIN RTOS_THREADS */
  /* add threads, ... */
  /* USER CODE END RTOS_THREADS */

}

/* USER CODE BEGIN Header_StartDefaultTask */
/**
  * @brief  Function implementing the defaultTask thread.
  * @param  argument: Not used
  * @retval None
  */
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void const * argument)
{
  /* USER CODE BEGIN StartDefaultTask */
	printf("222\r\n");
	  //osTimerStart(SwtmrHandle, 1000);
  /* Infinite loop */
  for(;;)
  {
	  osDelay(1);
  }
  /* USER CODE END StartDefaultTask */
}

/* USER CODE BEGIN Header_Get_Task_Fun */
/**
* @brief Function implementing the Get_Task thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_Get_Task_Fun */
void Get_Task_Fun(void const * argument)
{
  /* USER CODE BEGIN Get_Task_Fun */
	osEvent event;
	printf("666\r\n");
	float	temp = 0;
	float 	humd = 0;
	int 	HR	=0;
	float 	SPO2=0;

	char	databuf[1024];
	/* Infinite loop */
	for(;;)
	{

		if( osMessageWaiting( TestQueueHandle ) != 0 )
		{
			printf( "Queue should have been empty!\r\n" );
		}
#if  1
		printf("开始接收数据！\r\n");
		event = osMessageGet(TestQueueHandle, 	/* 消息队列的句�? */
			                 osWaitForever); /* 等待时间 �?直等 */

		if(osEventMessage == event.status)
		{
			printf("receive data:%ld\n\n", event.value.v);
#endif
			memset(databuf, 0, sizeof(databuf));

			//OLED_logo(500);
			report_tempRH_json(&temp,&humd);
			printf("temp:%f,humd:%f\r\n",temp,humd);

			//OLED_ShowTempHumdity(temp,humd,500);
			HAL_Delay(100);

			blood_Loop(&HR,&SPO2);
			report_heart_json(HR,SPO2);
			printf("HR:%f,SPO2:%f\r\n",(float)HR,SPO2);

			//OLED_ShowHRSPO2(HR,SPO2,500);
			HAL_Delay(100);
			snprintf(databuf,sizeof(databuf),"{\"Temperature\":\"%.2f\",\"Humidity\":\"%.2f\"HR\":\"%.f\",\"SPO2\":\"%.2f\"}",temp,humd,(float )HR,SPO2);
			printf("databuf is :%s\r\n", databuf);

			HAL_UART_Transmit(&huart2, (uint8_t *)databuf, strlen(databuf), 20);
			//HAL_Delay(500);
		}
		osDelay(1);
	}
  /* USER CODE END Get_Task_Fun */
}

/* USER CODE BEGIN Header_Ble_Task_Fun */
/**
* @brief Function implementing the Ble_Task thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_Ble_Task_Fun */
void Ble_Task_Fun(void const * argument)
{
  /* USER CODE BEGIN Ble_Task_Fun */
	//osThreadSuspend(Get_TaskHandle);/* 挂起Get任务 */
	printf("333\r\n");
	osThreadSuspend(Receive_TaskHandle);/* 挂起Receive任务 */
  /* Infinite loop */
  for(;;)
  {
	  send_at_cmds();
	  printf("蓝牙已打开，现在执行软件定时器！\r\n");
#if 0
	  xReturn.status = osMessagePut(TestQueueHandle, 	/* 消息队列的句�? */
                                   	   send_data1,      /* 发�?�的消息内容 */
									   0);              /* 等待时间 0 */

	  if(osOK == xReturn.status)
	  {
		  osThreadSuspendAll();
		  printf("消息 send_data1 发�?�成�?!\n\n");
		  osThreadResumeAll();
	  }
#endif
	  //osThreadResume(Receive_TaskHandle);/* 恢复Get任务 */
	  osThreadSuspend(Get_TaskHandle);/* 挂起Get任务 */
	  osThreadResume(Receive_TaskHandle);/* 恢复Receive任务 */
	  osTimerStart(SwtmrHandle, 5000);
	  printf("444\r\n");
	  osDelay(1);
  }
  /* USER CODE END Ble_Task_Fun */
}

/* USER CODE BEGIN Header_Receive_Task_Fun */
/**
* @brief Function implementing the Receive_Task thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_Receive_Task_Fun */
void Receive_Task_Fun(void const * argument)
{
  /* USER CODE BEGIN Receive_Task_Fun */
	 osStatus xReturn = osErrorValue;
  /* Infinite loop */
  for(;;)
  {
	    // 获取二值信号量 xSemaphore,没获取到则一直等待
	    xReturn = osSemaphoreWait(BinarySemHandle, /* 二值信号量句柄 */
	                               osWaitForever); /* 等待时间 */
	    if(osOK == xReturn)
	    {
	        printf("receive BinarySemHandle of data:%s\n", recvBuff);
	        memset(recvBuff, 0, BUFFER_SIZE);       /* 清零 */
	        if (strstr(g_uart2_rxbuf, "red1"))
	        {
	        	clear_uart2_rxbuf();
	        	HAL_GPIO_WritePin(GPIOC, RED_LED_Pin, GPIO_PIN_RESET);
	        }

	        if (strstr(g_uart2_rxbuf, "red0"))
	        {
	        	clear_uart2_rxbuf();
	        	HAL_GPIO_WritePin(GPIOC, RED_LED_Pin, GPIO_PIN_SET);
	        }
	    }
  }
  /* USER CODE END Receive_Task_Fun */
}

/* Swtmr_Callback function */
void Swtmr_Callback(void const * argument)
{
  /* USER CODE BEGIN Swtmr_Callback */
    TickType_t tick_num;
    osEvent xReturn;
    uint32_t send_data1 = 1;
    printf("555\r\n");

//    for(;;)
 //   {
		TmrCb_Count++; /* 每回调一次加一 */

		tick_num = osKernelSysTick(); /* 获取滴答定时器的计数值 */
		printf("swtmr_callback %d\n", TmrCb_Count);
		//printf("tick_num=%d\n", tick_num);
		osThreadSuspend(Ble_TaskHandle);/* 挂起Ble任务 */
    	if(TmrCb_Count%1 != 0)
    	{
    		printf("It's not sampling time yet!\r\n");
    	}
    	else
    	{
    		osThreadResume(Get_TaskHandle);/* 恢复Get任务 */

    		xReturn.status = osMessagePut(TestQueueHandle, 	/* 消息队列的句柄 */
    			                          send_data1,      /* 发送的消息内容 */
										  0);              /* 等待时间 0 */
#if 0
    		if(osOK == xReturn.status)
    		{
    			osThreadSuspendAll();
    			printf("消息 send_data1 发送成功!\n\n");
    			osThreadResumeAll();

    		}
#endif
    	}

  //  }
  /* USER CODE END Swtmr_Callback */
}

/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */
int report_heart_json(int HR,float SPO2)
{

	HR = g_blooddata.heart;
	SPO2 = g_blooddata.SpO2;

	return 0;
}


int report_tempRH_json(float *temperature,float *humidity)
{
	//char		buf[128];

	*temperature = sht20_sample_temp_or_hum(0xf3);
	*humidity = sht20_sample_temp_or_hum(0xf5);

	*temperature = *temperature/10.0;
	*humidity = *humidity/10.0;

	return 0;

}
/* USER CODE END Application */
